#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <event.h>
#include "common.h"
#include "http.h"
#include "queue.h"

queue q;
struct timeval timeout;

void echo(int fd,short event,void *arg);
int server_socket(int port);
int main(int argc,char **argv)
{
	int c;
	int dm=0;
	while ((c=getopt(argc,argv,"d"))!= -1)
	{
		switch(c)
		{
			case 'd':
				dm=1;
				break;
			default:
				break;
		}
	}
	if(dm)
	{
		daemon(0,0);
	}
	timeout.tv_sec=1;
	timeout.tv_usec=0;
	memset(&q,0,sizeof(q));
	int sockfd=server_socket(1902);
	event_init();
	struct event ev_recvfd;
	event_set(&ev_recvfd,sockfd,EV_READ,echo,&ev_recvfd);
	event_add(&ev_recvfd,NULL);
	event_dispatch();
}
int server_socket(int port)
{
	int sockfd,ret;
	struct sockaddr_in server_addr;
	memset(&server_addr,0,sizeof(server_addr));
	sockfd=socket(AF_INET,SOCK_DGRAM,0);
	int rcvbuf=4*1024*1024;
	int sndbuf=4*1024*1024;
	setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,(void *)&rcvbuf,sizeof(rcvbuf));
	setsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,(void *)&sndbuf,sizeof(sndbuf));
	if(set_nonblock(sockfd) != 0 )
	{
		close(sockfd);
		exit(-1);
	}
	if(sockfd < 0)
	{
		perror("socket:");
		exit(sockfd);
	}
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(port);
	ret=bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
	if(ret < 0)
	{
		perror("bind:");
		exit(ret);
	}
	return sockfd;
}


void echo(int sockfd,short event,void *arg)
{
	struct event *ev=arg;
	event_add(ev,NULL);
	struct sockaddr_in client_addr;
	socklen_t socklen;
	socklen=sizeof(client_addr);
	int ret=0;
	char msg[1024];
	memset(msg,0,sizeof(msg));
	ret=recvfrom(sockfd,msg,1024,0,(struct sockaddr *)&client_addr,&socklen);
	
	int http_fd;
	if(is_empty(&q))
	{
		http_fd=client_socket("218.30.115.226",80);
		if(http_fd < 0)
			return;
	}
	else
	{
		queue_get(&q,&http_fd);
	}
	conn *http_cw=calloc(1,sizeof(conn));
	strncpy(http_cw->http_url,msg,sizeof(http_cw->http_url));
	http_cw->udp_fd=sockfd;
	http_cw->client_addr=client_addr;
	event_set(&(http_cw->ev),http_fd,EV_WRITE,http_write,http_cw);
	event_add(&(http_cw->ev),&timeout);
}
